package main

import (
	"context"
	"fmt"
	"log"
	"os"
	"path/filepath"
	"strings"
	"time"

	"go-file-perception-model/internal/config"
	"go-file-perception-model/internal/logger"
	"go-file-perception-model/internal/model"
	"go-file-perception-model/internal/repository"
	"go-file-perception-model/internal/service"
	"go-file-perception-model/pkg/embedding"
	"go-file-perception-model/pkg/vector"
)

func main() {
	fmt.Println("=== 向量存储修复验证测试 ===")

	// 初始化日志系统
	logger.InitLogger()

	// 加载配置
	cfg, err := config.LoadConfig()
	if err != nil {
		log.Fatalf("Failed to load config: %v", err)
	}

	// 初始化嵌入模型
	bgeConfig := &embedding.BGEServiceConfig{
		Host:    cfg.BGEService.Host,
		Port:    cfg.BGEService.Port,
		APIKey:  cfg.BGEService.APIKey,
		Timeout: cfg.BGEService.Timeout,
	}
	embeddingModel, err := embedding.NewBGEModel(bgeConfig)
	if err != nil {
		log.Printf("Warning: Failed to initialize embedding model: %v", err)
		embeddingModel = nil
	}

	// 初始化向量数据库
	var vectorDB *vector.QdrantDB
	vectorDB, err = vector.NewQdrantDBWithAPIKey(cfg.VectorDB.Host, cfg.VectorDB.Port, cfg.VectorDB.APIKey)
	if err != nil {
		vectorDB, err = vector.NewQdrantDBWithAPIKey(cfg.VectorDB.Host, cfg.VectorDB.GRPCPort, cfg.VectorDB.APIKey)
		if err != nil {
			log.Fatalf("Failed to connect to vector database: %v", err)
		}
	}

	// 初始化存储库和服务
	fileRepo := repository.NewFileRepository(vectorDB)
	fileService := service.NewFileService(fileRepo, embeddingModel, &cfg.FileIndex)

	fmt.Println("✅ 1. 服务初始化成功")

	// 创建测试文件
	testDir := "test_vector_storage"
	testFile := filepath.Join(testDir, "test.md")
	
	if err := os.MkdirAll(testDir, 0755); err != nil {
		log.Fatalf("Failed to create test directory: %v", err)
	}
	defer os.RemoveAll(testDir)

	testContent := `# 测试文档

这是一个测试文档，用来验证向量存储功能是否正常工作。

## 第一节
这一节包含了一些测试内容，用来验证文本分块和向量化是否正常。

## 第二节
这一节包含了更多的测试内容，用来验证语义分块功能。

## 第三节
最后一节用来确保所有的分块都能正确存储到向量数据库中。`

	if err := os.WriteFile(testFile, []byte(testContent), 0644); err != nil {
		log.Fatalf("Failed to create test file: %v", err)
	}

	fmt.Println("✅ 2. 测试文件创建成功")

	// 设置索引目录
	if err := fileService.SetIndexDirectories([]string{testDir}); err != nil {
		log.Fatalf("Failed to set index directories: %v", err)
	}

	fmt.Println("✅ 3. 索引目录设置成功")

	// 开始索引
	indexReq := model.IndexRequest{
		Directories: []string{testDir},
		Recursive:   false,
		Force:       true,
	}

	taskID, err := fileService.StartIndexing(indexReq)
	if err != nil {
		log.Fatalf("Failed to start indexing: %v", err)
	}

	fmt.Printf("✅ 4. 索引任务启动成功，任务ID: %s\n", taskID)

	// 等待索引完成
	fmt.Println("等待索引完成...")
	for i := 0; i < 30; i++ { // 最多等待30秒
		time.Sleep(1 * time.Second)
		status, err := fileService.GetIndexStatus()
		if err != nil {
			log.Printf("Failed to get index status: %v", err)
			continue
		}
		
		if !status.IsIndexing {
			fmt.Printf("✅ 5. 索引完成！总分块数: %d\n", status.TotalChunks)
			break
		}
		
		if i == 29 {
			log.Fatalf("索引超时")
		}
	}

	// 验证SQLite数据库
	fmt.Println("\n=== SQLite数据库验证 ===")
	cwd, _ := filepath.Abs(".")
	dbPath := filepath.Join(cwd, "data", "file_monitor.db")
	fileMonitorRepo, err := repository.NewFileMonitorRepository(dbPath)
	if err != nil {
		log.Fatalf("Failed to connect to SQLite: %v", err)
	}

	directories, err := fileMonitorRepo.ListAllDirectoryRecords()
	if err != nil {
		log.Fatalf("Failed to list directories: %v", err)
	}

	if len(directories) == 0 {
		log.Fatalf("❌ 没有找到目录记录")
	}

	fmt.Printf("✅ 找到 %d 个目录记录\n", len(directories))

	for _, dir := range directories {
		if strings.Contains(dir.DirectoryPath, testDir) {
			fmt.Printf("  目录: %s\n", dir.DirectoryPath)
			fmt.Printf("  集合名称: %s\n", dir.CollectionName)
			
			files, err := fileMonitorRepo.GetFileRecordsByDirectoryID(dir.ID)
			if err != nil {
				log.Printf("Failed to get file records: %v", err)
				continue
			}
			
			fmt.Printf("  文件记录数: %d\n", len(files))
			
			indexedCount := 0
			for _, file := range files {
				if file.IsIndexed {
					indexedCount++
				}
			}
			fmt.Printf("  已索引文件数: %d\n", indexedCount)
			
			// 验证向量数据库
			fmt.Println("\n=== 向量数据库验证 ===")
			vectorDB.SetCollection(dir.CollectionName)
			
			count, err := vectorDB.CountPoints(context.Background(), nil)
			if err != nil {
				log.Printf("❌ 无法计算向量点数量: %v", err)
			} else {
				fmt.Printf("✅ 向量点数量: %d\n", count)
				
				if count > 0 {
					fmt.Println("🎉 向量存储修复成功！")
					fmt.Println("   - SQLite中有文件记录")
					fmt.Printf("   - 向量数据库中有 %d 个分块\n", count)
					fmt.Println("   - 数据存储一致性正常")
				} else {
					fmt.Println("❌ 向量数据库中没有数据")
				}
			}
			break
		}
	}

	fmt.Println("\n=== 测试完成 ===")
}